/**
 * /**
 *  ** 加法函数，用来得到精确的加法结果
 *  ** 说明：javascript的加法结果会有误差，在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果,不分格式。
 *  ** 调用：accAdd(arg1,arg2)
 * @param a
 * @param b
 ** 返回值：x加上y的精确结果
 */
export function add(a: any, b: any) {
  a = a || 0;
  b = b || 0;
  let c: number, d: number, e: number;
  try {
    c = a.toString().split(".")[1]?.length ?? 0;
  } catch (e) {
    console.log(e);
    c = 0;
  }
  try {
    d = b.toString().split(".")[1]?.length ?? 0;
  } catch (e) {
    console.log(e);
    d = 0;
  }
  return (e = Math.pow(10, Math.max(c, d))), (mul(a, e) + mul(b, e)) / e;
}

/**
 ** 减法函数，用来得到精确的减法结果
 ** 说明：javascript的减法结果会有误差，在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
 * @param a
 * @param b
 ** 返回值：x减去y的精确结果
 */
export function sub(a: any, b: any) {
  a = a || 0;
  b = b || 0;
  let c: number, d: number, e: number;
  try {
    c = a.toString().split(".")[1]?.length ?? 0;
  } catch (e) {
    console.log(e);
    c = 0;
  }
  try {
    d = b.toString().split(".")[1]?.length ?? 0;
  } catch (e) {
    console.log(e);
    d = 0;
  }
  return (e = Math.pow(10, Math.max(c, d))), (mul(a, e) - mul(b, e)) / e;
}

/**
 * * 乘法函数，用来得到精确的乘法结果
 * * 说明：javascript的乘法结果会有误差，在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
 * @param a
 * @param b
 * * 返回值：a乘以 b的精确结果
 */
export function mul(a = 0, b = 0) {
  a = a || 0;
  b = b || 0;
  let c = 0,
    d = a.toString(),
    e = b.toString();
  try {
    c += d.split(".")[1]?.length ?? 0;
  } catch (e) {
    console.log(e);
  }
  try {
    c += e.split(".")[1]?.length ?? 0;
  } catch (e) {
    console.log(e);
  }
  return (
    (Number(d.replace(".", "")) * Number(e.replace(".", ""))) / Math.pow(10, c)
  );
}

/**
 * * 除法函数，用来得到精确的除法结果
 * * 说明：javascript的除法结果会有误差，在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
 * @param a
 * @param b
 * * 返回值：a除以b的精确结果
 */
export function div(a = 0, b = 0) {
  a = a || 0;
  b = b || 0;
  let c,
    d,
    e = 0,
    f = 0,
    r;

  try {
    e = a.toString().split(".")[1]?.length ?? 0;
  } catch (e) {
    console.log(e);
  }
  try {
    f = b.toString().split(".")[1]?.length ?? 0;
  } catch (e) {
    console.log(e);
  }
  c = Number(a.toString().replace(".", ""));
  d = Number(b.toString().replace(".", ""));
  r = f - e;
  if (Math.abs(a) < 1 || Math.abs(b) < 1) {
    // 修复除小数的bug
    if (f > e) {
      c = c * Math.pow(10, f - e);
    }
    if (e > f) {
      d = d * Math.pow(10, e - f);
    }
    r = 0;
  }
  return mul(c / d, Math.pow(10, r));
}

/**
 * 四舍五入取小数点
 * @param num
 * @param s
 */
export function toFixed(num: any, s: number) {
  if (num.toString().split(".").length === 1) return num + "";
  const times = Math.pow(10, s);
  let des = add(mul(num, times), 0.5);
  des = div(parseInt(des, 10), times);
  return des + "";
}

/**
 * 小数点位向下取整
 * @param num
 * @param s
 */
export function integerNum(num: any, s: number) {
  const times = Math.pow(10, s);
  let des = mul(num, times);
  des = div(parseInt(des, 10), times);
  return des;
}

// 对象数组去重
export function uniqueObjArray(target: [], prop: string) {
  const obj = {};
  target = target.reduce((cur: any, next: any) => {
    if (!obj[next[prop]]) {
      obj[next[prop]] = true;
      cur.push(next);
    }
    return cur;
  }, []); // 设置cur默认类型为数组，并且初始值为空的数组
  return target;
}
